package mt.omid.dimomuth.bus;


import static mt.omid.dimomuth.bus.ExtMessage.*;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

import mt.omid.dimomuth.mgm.MgmHandler;


/***
 * Bus Protocol indentity is the pair of sender and receiver id
 * 
 * @author omid
 * 
 */

public class BusProtocol implements Runnable
{

    private Socket   clntSock;
    private Logger   logger;
    // private MgmHandler hndl;

    private int      remoteId;
    private int      remoteInst;
    
    private DataBus bus;

    DataInputStream  reader;
    DataOutputStream writer;


    public BusProtocol( Socket sock, Logger lgr, DataBus db )
    {
	this.clntSock = sock;
	this.logger = lgr;
	this.bus = db;
    }

    public void handleRequest( Socket sock )
    {
	try
	{
	    reader = new DataInputStream( sock.getInputStream() );
	    writer = new DataOutputStream(sock.getOutputStream() );

	    byte [] header = new byte [ HEADER_SIZE ];
	    byte [] data;	// create data byte array after getting length

	    while( reader.read( header ) == HEADER_SIZE )
	    {
		// Now read data part
		ExtMessage msg = decodeHeader( header ); 
		data = new byte[ msg.len ];
		if( reader.read(  data ) != msg.len )
		    	break;
		msg.data = data;
		bus.insert( msg );
		logger.finest( "CBMessage received:" + msg );
	    }
	    logger.warning( "Exiting listener loop because of bad header or data part reading." );
	}
	catch( IOException ie )
	{
	    logger.log( Level.WARNING, "Exception in Data Bus Protocol", ie );
	}
	finally
	{
	    try
	    {
		sock.close();
	    }
	    catch( IOException ie )
	    {
		logger.log( Level.WARNING, "Exception in closing socket of this data bus connection.", ie );
	    }
	}
    }

    public void write( byte [] buf ) throws IOException
    {
	writer.write( buf );
    }

    public void run()
    {
	handleRequest( clntSock );
    }
}
